package com.jijunpeng.javafx.cipher.controller;

import com.jijunpeng.javafx.cipher.common.DialogUtil;
import com.jijunpeng.javafx.cipher.common.LetterCaseEnum;
import com.jijunpeng.javafx.cipher.common.enums.CharsetEnum;
import com.jijunpeng.javafx.cipher.common.enums.CipherProviderEnum;
import com.jijunpeng.javafx.cipher.controller.api.BaseController;
import com.jijunpeng.javafx.cipher.controller.api.ICipherController;
import com.jijunpeng.javafx.cipher.persistence.PersistenceJson;
import javafx.event.ActionEvent;
import javafx.fxml.FXML;
import javafx.scene.control.ComboBox;
import javafx.scene.control.RadioButton;
import javafx.scene.control.TextArea;
import javafx.scene.layout.Pane;
import lombok.Getter;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.codec.digest.DigestUtils;

import java.util.function.Function;

/**
 * @author Ji Junpeng
 * @date 2019-12-10 23:46
 */
@Getter
@Slf4j
@PersistenceJson(path = "$.main_inner_$hash")
public class HashController extends BaseController implements ICipherController {

    @FXML
    private Pane hashRootPane;
    @FXML
    @PersistenceJson(path = "leftHexRb", field = "selected", getter = "isSelected")
    private RadioButton leftHexRb;
    @FXML
    @PersistenceJson(path = "leftBase64Rb", field = "selected", getter = "isSelected")
    private RadioButton leftBase64Rb;
    @FXML
    @PersistenceJson(path = "leftStringRb", field = "selected", getter = "isSelected")
    private RadioButton leftStringRb;
    @FXML
    @PersistenceJson(path = "rightHexRb", field = "selected", getter = "isSelected")
    private RadioButton rightHexRb;
    @FXML
    @PersistenceJson(path = "rightBase64Rb", field = "selected", getter = "isSelected")
    private RadioButton rightBase64Rb;
    @FXML
    @PersistenceJson(path = "leftStringCharsetComboBox", field = "value")
    private ComboBox<CharsetEnum> leftStringCharsetComboBox;
    @FXML
    @PersistenceJson(path = "rightHexCaseComboBox", field = "value")
    private ComboBox<LetterCaseEnum> rightHexCaseComboBox;
    @FXML
    @PersistenceJson(path = "leftTextArea", field = "text")
    private TextArea leftTextArea;
    @FXML
    @PersistenceJson(path = "rightTextArea", field = "text")
    private TextArea rightTextArea;

    @Override
    protected Pane getRootPane() {
        return hashRootPane;
    }

    @Override
    protected void initViewData() {
        initCipherController();
    }

    @Override
    public ComboBox<CipherProviderEnum> getCipherProviderComboBox() {
        return null;
    }

    @FXML
    private void genMd5(ActionEvent actionEvent) {
        try {
            convert(DigestUtils::md5);
        } catch (Exception e) {
            log.error("md5 gen error. input:{}", leftTextArea.getText());
            DialogUtil.showError(hashRootPane, "计算MD5失败", "错误原因：" + e.getMessage());
        }
    }

    @FXML
    private void genSha1(ActionEvent actionEvent) {
        try {
            convert(DigestUtils::sha1);
        } catch (Exception e) {
            log.error("md5 gen error. input:{}", leftTextArea.getText());
            DialogUtil.showError(hashRootPane, "计算SHA1失败", "错误原因：" + e.getMessage());
        }
    }

    @FXML
    private void genSha256(ActionEvent actionEvent) {
        try {
            convert(DigestUtils::sha256);
        } catch (Exception e) {
            log.error("md5 gen error. input:{}", leftTextArea.getText());
            DialogUtil.showError(hashRootPane, "计算SHA256失败", "错误原因：" + e.getMessage());
        }
    }

    @FXML
    private void genSha512(ActionEvent actionEvent) {
        try {
            convert(DigestUtils::sha512);
        } catch (Exception e) {
            log.error("md5 gen error. input:{}", leftTextArea.getText());
            DialogUtil.showError(hashRootPane, "计算SHA512失败", "错误原因：" + e.getMessage());
        }
    }

    private void convert(Function<byte[], byte[]> hashFunction) throws Exception {
        byte[] leftBytes = getLeftBytes();
        byte[] rightBytes = hashFunction.apply(leftBytes);
        String rightStr = buildRightStr(rightBytes);
        rightTextArea.setText(rightStr);
    }
}
